package com.seu.vcampus.server;

import com.seu.vcampus.handler.LibraryHandler;
import com.seu.vcampus.handler.ShopHandler;
import com.seu.vcampus.message.Message;
import com.seu.vcampus.srv.UserService;
import com.seu.vcampus.vo.User;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 虚拟校园服务器类
 * 负责处理客户端连接和消息处理
 * 
 * @author 虚拟校园开发团队
 * @since 1.0.0
 */
public class VCampusServer {
    private static final Logger logger = LoggerFactory.getLogger(VCampusServer.class);
    
    private final int port;
    private ServerSocket serverSocket;
    private ExecutorService threadPool;
    private Connection databaseConnection;
    private UserService userService;
    private LibraryHandler libraryHandler;
    private ShopHandler shopHandler;
    
    public VCampusServer(int port) {
        this.port = port;
    }
    
    /**
     * 启动服务器
     */
    public void start() {
        try {
            initializeDatabase();
            initializeServices();
            
            serverSocket = new ServerSocket(port);
            threadPool = Executors.newCachedThreadPool();
            
            logger.info("虚拟校园服务器已启动，监听端口: {}", port);
            
            while (!serverSocket.isClosed()) {
                Socket clientSocket = serverSocket.accept();
                logger.info("客户端连接: {}", clientSocket.getInetAddress());
                
                threadPool.execute(new ClientHandler(clientSocket));
            }
            
        } catch (IOException e) {
            logger.error("服务器启动失败", e);
        }
    }
    
    /**
     * 停止服务器
     */
    public void stop() {
        try {
            if (threadPool != null) {
                threadPool.shutdown();
            }
            
            if (serverSocket != null) {
                serverSocket.close();
            }
            
            if (databaseConnection != null) {
                databaseConnection.close();
            }
            
            logger.info("虚拟校园服务器已停止");
            
        } catch (IOException | SQLException e) {
            logger.error("服务器停止时出错", e);
        }
    }
    
    /**
     * 初始化数据库连接
     */
    private void initializeDatabase() {
        try {
            String url = "jdbc:sqlite:vcampus.db";
            databaseConnection = DriverManager.getConnection(url);
            logger.info("数据库连接成功");
        } catch (SQLException e) {
            logger.error("数据库连接失败", e);
            throw new RuntimeException("无法连接数据库", e);
        }
    }
    
    /**
     * 初始化服务
     */
    private void initializeServices() {
        // 使用共享连接初始化服务（用于只读操作）
        userService = new UserService(databaseConnection);
        libraryHandler = new LibraryHandler(databaseConnection);
        shopHandler = new ShopHandler(databaseConnection);
        logger.info("服务初始化完成");
    }
    
    /**
     * 客户端处理器内部类
     */
    private class ClientHandler implements Runnable {
        private final Socket clientSocket;
        private ObjectInputStream in;
        private ObjectOutputStream out;
        private String currentUserId;
        private User.UserType currentUserType;
        
        public ClientHandler(Socket clientSocket) {
            this.clientSocket = clientSocket;
        }

        @Override
        public void run() {
            try {
                out = new ObjectOutputStream(clientSocket.getOutputStream());
                in = new ObjectInputStream(clientSocket.getInputStream());
                
                while (!clientSocket.isClosed()) {
                    Message request = (Message) in.readObject();
                    Message response = handleRequest(request);
                    
                    out.writeObject(response);
                    out.flush();
                }
                
            } catch (IOException | ClassNotFoundException e) {
                logger.error("客户端处理出错", e);
            } finally {
                closeConnection();
            }
        }
        
        /**
         * 处理客户端请求
         * @param request 请求消息
         * @return 响应消息
         */
        private Message handleRequest(Message request) {
            try {
                Message response;
                // 为每个客户端请求创建独立的数据库连接，确保事务隔离
                try (Connection clientConnection = DriverManager.getConnection("jdbc:sqlite:vcampus.db")) {
                    UserService clientUserService = new UserService(clientConnection);
                    LibraryHandler clientLibraryHandler = new LibraryHandler(clientConnection);
                    
                    // 处理登录请求
                    if (request.getType() == Message.Type.LOGIN_REQUEST) {
                        response = clientUserService.login(request);
                        if (response.isSuccess()) {
                            User user = (User) response.getPayload();
                            currentUserId = user.getUserId();
                            currentUserType = user.getUserType();
                        }
                        return response;
                    }
                    
                    // 处理注销请求
                    if (request.getType() == Message.Type.LOGOUT_REQUEST) {
                        response = clientUserService.logout(request);
                        currentUserId = null;
                        currentUserType = null;
                        return response;
                    }
                    
                    // 验证权限 - 对于需要权限的操作
                    if (!hasPermission(request.getType())) {
                        return Message.error("权限不足");
                    }
                    
                    switch (request.getType()) {
                        case REGISTER_REQUEST:
                            response = clientUserService.register(request);
                            break;
                        case GET_USER_REQUEST:
                            Object payload = request.getPayload();
                            if (payload instanceof String) {
                                String strPayload = (String) payload;
                                if ("all".equals(strPayload)) {
                                    response = clientUserService.getAllUsers(request);
                                } else {
                                    response = clientUserService.getUser(request);
                                }
                            } else if (payload instanceof Object[]) {
                                // 搜索用户请求
                                response = clientUserService.searchUsers(request);
                            } else {
                                response = Message.error("无效的请求参数");
                            }
                            break;
                        case UPDATE_USER_REQUEST:
                            response = clientUserService.updateUser(request);
                            break;
                        case DELETE_USER_REQUEST:
                            response = clientUserService.deleteUser(request);
                            break;
                        // 权限相关请求
                        case GET_PERMISSIONS_REQUEST:
                            response = handleGetPermissionsRequest(clientUserService, request);
                            break;
                        case CHECK_PERMISSION_REQUEST:
                            response = handleCheckPermissionRequest(clientUserService, request);
                            break;
                        case ADD_PERMISSION_REQUEST:
                            response = handleAddPermissionRequest(clientUserService, request);
                            break;
                        case REMOVE_PERMISSION_REQUEST:
                            response = handleRemovePermissionRequest(clientUserService, request);
                            break;
                        // 图书馆相关请求
                        case GET_BOOKS_REQUEST:
                        case SEARCH_BOOKS_REQUEST:
                        case BORROW_BOOK_REQUEST:
                        case RETURN_BOOK_REQUEST:
                        case GET_BORROW_RECORDS_REQUEST:
                            response = clientLibraryHandler.handle(request);
                            break;
                        default:
                            response = Message.error("未知请求类型");
                            break;
                    }
                }
                return response;
            } catch (Exception e) {
                logger.error("处理请求失败", e);
                return Message.error("处理请求失败: " + e.getMessage());
            }
        }
        
        /**
     * 检查用户是否有权限执行指定操作
     * @param requestType 请求类型
     * @return 是否有权限
     */
    private boolean hasPermission(Message.Type requestType) {
        if (currentUserId == null || currentUserType == null) {
            return false;
        }
        
        // currentUserType是User.UserType枚举类型
        User.UserType userType = currentUserType;
        
        // 使用if-else代替switch，避免枚举switch case问题
        if (requestType == Message.Type.GET_USER_REQUEST ||
            requestType == Message.Type.UPDATE_USER_REQUEST ||
            requestType == Message.Type.DELETE_USER_REQUEST) {
            // 用户管理需要管理员权限
            return userType == User.UserType.ADMIN || userType == User.UserType.SYSTEM_ADMIN;
        }
        
        if (requestType == Message.Type.ADD_PERMISSION_REQUEST ||
            requestType == Message.Type.REMOVE_PERMISSION_REQUEST ||
            requestType == Message.Type.GET_PERMISSIONS_REQUEST) {
            // 权限管理需要系统管理员权限
            return userType == User.UserType.SYSTEM_ADMIN;
        }
        
        if (requestType == Message.Type.GET_BOOKS_REQUEST ||
            requestType == Message.Type.SEARCH_BOOKS_REQUEST ||
            requestType == Message.Type.BORROW_BOOK_REQUEST ||
            requestType == Message.Type.RETURN_BOOK_REQUEST ||
            requestType == Message.Type.GET_BORROW_RECORDS_REQUEST ||
            requestType == Message.Type.GET_ALL_BORROW_RECORDS_REQUEST) {
            // 图书管理需要图书馆管理员权限
            return userType == User.UserType.LIBRARY_ADMIN || userType == User.UserType.SYSTEM_ADMIN;
        }
        
        return true; // 其他请求不需要特殊权限
    }
        
        /**
         * 处理获取权限请求
         */
        private Message handleGetPermissionsRequest(UserService userService, Message request) {
            try {
                String userId = (String) request.getPayload();
                List<String> permissions = userService.getUserPermissions(userId);
                return Message.success(Message.Type.GET_PERMISSIONS_RESPONSE, permissions);
            } catch (Exception e) {
                logger.error("获取权限失败", e);
                return Message.error("获取权限失败: " + e.getMessage());
            }
        }
        
        /**
         * 处理检查权限请求
         */
        private Message handleCheckPermissionRequest(UserService userService, Message request) {
            try {
                String[] params = (String[]) request.getPayload();
                String userId = params[0];
                String permission = params[1];
                boolean hasPermission = userService.hasPermission(userId, permission);
                return Message.success(Message.Type.CHECK_PERMISSION_RESPONSE, hasPermission);
            } catch (Exception e) {
                logger.error("检查权限失败", e);
                return Message.error("检查权限失败: " + e.getMessage());
            }
        }
        
        /**
         * 处理添加权限请求
         */
        private Message handleAddPermissionRequest(UserService userService, Message request) {
            try {
                String[] params = (String[]) request.getPayload();
                String userId = params[0];
                String permission = params[1];
                boolean success = userService.addPermission(userId, permission);
                return Message.success(Message.Type.ADD_PERMISSION_RESPONSE, success);
            } catch (Exception e) {
                logger.error("添加权限失败", e);
                return Message.error("添加权限失败: " + e.getMessage());
            }
        }
        
        /**
         * 处理删除权限请求
         */
        private Message handleRemovePermissionRequest(UserService userService, Message request) {
            try {
                String[] params = (String[]) request.getPayload();
                String userId = params[0];
                String permission = params[1];
                boolean success = userService.removePermission(userId, permission);
                return Message.success(Message.Type.REMOVE_PERMISSION_RESPONSE, success);
            } catch (Exception e) {
                logger.error("删除权限失败", e);
                return Message.error("删除权限失败: " + e.getMessage());
            }
        }
        
        /**
         * 关闭连接
         */
        private void closeConnection() {
            try {
                if (in != null) {
                    in.close();
                }
            } catch (IOException e) {
                logger.error("关闭输入流时出错", e);
            }
            try {
                if (out != null) {
                    out.close();
                }
            } catch (IOException e) {
                logger.error("关闭输出流时出错", e);
            }
            try {
                if (clientSocket != null) {
                    clientSocket.close();
                }
            } catch (IOException e) {
                logger.error("关闭客户端套接字时出错", e);
            }
            logger.info("客户端断开连接: {}", clientSocket != null ? clientSocket.getInetAddress() : "unknown");
        }
    }
}